#include "03_header.h"

#define DB_HOST "localhost"   //127.0.0.1
#define DB_USER "root"        //登录mysql使用的用户名
#define DB_PASS "123456"      //登录mysql使用的密码
#define DB_NAME "netdisk_3"   //数据库名，已定好


int sendTrain(int sockfd, int type, const char *value) {
    train_t train;
    train.type = type;
    train.lenth = strlen(value);
    memset(train.value, 0, sizeof(train.value));
    
    if (value) {
        strncpy(train.value, value, sizeof(train.value) - 1);
    }
    

    if (send(sockfd, &train, sizeof(int) * 2 + train.lenth, 0) <= 0) {
        perror("发送数据失败");
        return -1;
    }
    
    return 0;
}


int receiveTrain(int sockfd, train_t *train) {
    bzero(train, sizeof(train_t));
    
    // 先接收type和lenth
    if (recv(sockfd, train, sizeof(int) * 2, 0) <= 0) {
        perror("接收头部失败");
        return -1;
    }
    
    if (train->lenth > 0) {
        if (train->lenth >= (int)sizeof(train->value)) {
            fprintf(stderr, "数据长度超出缓冲区大小\n");
            return -1;
        }
        
        if (recv(sockfd, train->value, train->lenth, 0) <= 0) {
            perror("接收数据失败");
            return -1;
        }
        train->value[train->lenth] = '\0';  // 确保字符串正确终止
    }
    
    return 0;
}

char* generateSalt() {// 生成随机salt
    static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
    static char salt[21];
    strcpy(salt, "$6$");
    srand(time(NULL));
    for (int i = 3; i < 19; i++) {
        int index = rand() % 64;
        salt[i] = charset[index];
    }
    salt[19] = '$';
    salt[20] = '\0';
    return salt;
}

//int createUserDirectory(const char *basePath, const char *username) {
//    char userDir[1024];
//    snprintf(userDir, sizeof(userDir), "%s/%s", basePath, username);
//    struct stat st = {0};
//    if (stat(basePath, &st) == -1) {
//        fprintf(stderr, "Base path %s does not exist!\n", basePath);
//        return -1;
//    }
//    if (stat(userDir, &st) == -1) {
//        if (mkdir(userDir, 0700) != 0) {
//            perror("mkdir failed");
//            return -1;
//        }
//        printf("Created user directory: %s\n", userDir);
//    }
//    return 0;
//}

int signInAndAuthPasswd(int netfd, char* basePath, int size, char *pUsername, MYSQL *conn) {
    train_t train;
    MYSQL_RES *result;
    MYSQL_ROW row;
    
    //conn = mysql_init(NULL);
    //if (conn == NULL) {
    //    fprintf(stderr, "mysql_init() failed\n");
    //    return -1;
    //}
    //
    //if (mysql_real_connect(conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, 0, NULL, 0) == NULL) {
    //    fprintf(stderr, "mysql_real_connect() failed\n");
    //    mysql_close(conn);
    //    return -1;
    //}
    
    if (receiveTrain(netfd, &train) < 0) {
        mysql_close(conn);
        return -1;
    }
    
    int reqType = train.type;
    char username[256];
    strcpy(username, train.value);
    strcpy(pUsername, train.value);
	printf("收到请求类型: %d, 用户名: %s\n", reqType, username);
    
    if (reqType == SIGN_IN) {//注册部分
        printf("Processing registration for user: %s\n", username);
        char *salt = generateSalt();//生成随机的salt值
        char query[1024];
		//将收到的username和对应唯一的salt值insert 到 用户表
        snprintf(query, sizeof(query), 
                "INSERT INTO user_info(username, salt, is_deleted) VALUES('%s', '%s', 0) ON DUPLICATE KEY UPDATE salt='%s', is_deleted=0", 
                username, salt, salt);
        if (mysql_query(conn, query)) {
            fprintf(stderr, "INSERT failed: %s\n", mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
		//将salt值发送给客户端，等待客户端将密码加密为密文
        if (sendTrain(netfd, SIGN_IN, salt) < 0) {
            mysql_close(conn);
            return -1;
        }
        printf("type = %d\n",train.type);
		//接收客户端解密后的密文
        if (receiveTrain(netfd, &train) < 0) {
            mysql_close(conn);
            return -1;
        }
        char encryptedPass[256];
        strcpy(encryptedPass, train.value);
		//将密文更新到用户表该用户所对应的列
        snprintf(query, sizeof(query), 
                "UPDATE user_info SET encrypt_passwd='%s' WHERE username='%s'", 
                encryptedPass, username);
        if (mysql_query(conn, query)) {
            fprintf(stderr, "UPDATE failed: %s\n", mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
//        // 创建用户目录并更新basePath
//        if (createUserDirectory(basePath, username) < 0) {
//            fprintf(stderr, "Failed to create directory for user %s\n", username);
//       
//        } else {
//            char tempPath[1024];
//            snprintf(tempPath, sizeof(tempPath), "%s/%s", basePath, username);
//            strncpy(basePath,tempPath,size);
//        }
        if (sendTrain(netfd, SIGN_IN, "SUCCESS") < 0) {
            mysql_close(conn);
            return -1;
        }
    } else if (reqType == AUTH) {//登录部分
        printf("Processing authentication for user: %s\n", username);
        char query[1024];
		//与注册类似，拿到用户名后取出salt发送给客户端，密文用于稍后与客户端发来的密文密码作对比
        snprintf(query, sizeof(query), 
                "SELECT salt, encrypt_passwd FROM user_info WHERE username='%s' AND is_deleted=0", 
                username);
        if (mysql_query(conn, query)) {
            fprintf(stderr, "SELECT failed: %s\n", mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
        result = mysql_store_result(conn);
        if (result == NULL) {
            fprintf(stderr, "mysql_store_result() failed\n");
            mysql_close(conn);
            return -1;
        }
        if (mysql_num_rows(result) != 1) {
            mysql_free_result(result);
            mysql_close(conn);
            sendTrain(netfd, AUTH, "FAILURE");
            return -1;
        }
        row = mysql_fetch_row(result);
        char salt[256];
        char storedPass[256];
        strcpy(salt, row[0]);
        strcpy(storedPass, row[1]);
        mysql_free_result(result);
		//发送salt给客户端
        if (sendTrain(netfd, AUTH, salt) < 0) {
            mysql_close(conn);
            return -1;
        }
		//接收密文
        if (receiveTrain(netfd, &train) < 0) {
            mysql_close(conn);
            return -1;
        }
        char clientPass[256];//存放接收的密文
        strcpy(clientPass, train.value);
        if (strcmp(clientPass, storedPass) == 0) {
//            if (createUserDirectory(basePath, username) < 0) {
//                fprintf(stderr, "Failed to create directory for user %s\n", username);
//                sendTrain(netfd, AUTH, "FAILURE");
//                mysql_close(conn);
//                return -1;
//            }
            char tempPath[1024];
            snprintf(tempPath, sizeof(tempPath), "%s/%s", basePath, username);
            strncpy(basePath,tempPath,size);
            if (sendTrain(netfd, AUTH, "SUCCESS") < 0) {
                mysql_close(conn);
                return -1;
            }
        } else {
            sendTrain(netfd, AUTH, "FAILURE");
            mysql_close(conn);
            return -1;
        }
    } else if (reqType == DEL) {//注销
        printf("Processing account deletion for user: %s\n", username);
        char query[1024];
        snprintf(query, sizeof(query), 
                "DELETE from user_info WHERE username='%s'", 
                username);
        if (mysql_query(conn, query)) {
            fprintf(stderr, "UPDATE failed: %s\n", mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
        if (sendTrain(netfd, DEL, "SUCCESS") < 0) {
            mysql_close(conn);
            return -1;
        }
        return -2;//-2代表是删除用户
    } else {
        printf("Unknown command type: %d\n", reqType);
        mysql_close(conn);
        return -1;
    }
    
    //mysql_close(conn);
    return 0;
}

